t-SNEを用いた多様体学習(manifold learning algorithms with t-SNE)
Overview
データを変換して散布図で可視化したいときは、まずPCAを用いることは悪くはありませんが、PCAの性質上(回転していくつかの方向を落とす)、その有用性は限られます。そこで、多様体学習アルゴリズムという一連のアルゴリズムが、よく可視化に用いられます。特に有用なのがt-SNEアルゴリズムです。
Theory
多様体学習は、テストセットに適用することはできず、訓練に使ったデータを変換することしかできません。また、多様体学習は、探索的なデータ解析に有用ですが、最終的な目的が教師あり学習の場合にはほとんど用いられません。
t-SNEは、データポイントの距離を可能な限り維持する2次元表現を見つけようとします。まず最初にランダムな2次元表現を作り、そこから、もとの特徴量で近いデータポイントを近くに、遠いデータポイントを遠くに配置しようとします。つまり、どの点が近傍か示す情報を維持しようとします。
Coding
digitsデータセット
https://gyazo.com/f1f42e6c611779e1f2e865dee4a1c8cf
digitsデータセットにPCAを適用する
code: Python
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
digits = load_digits()
# PCAモデルを構築
pca = PCA(n_components=2)
pca.fit(digits.data)
# 数値データを最初の2主成分で変型
digits_pca = pca.transform(digits.data)
colors = ["#476A2A", "#7851B8", "#BD3430", "#4A2D4E", "#875525",
"#A83683", "#4E655E", "#853541", "#3A3120", "#535D8E"]
plt.figure(figsize=(10, 10))
plt.xlim(digits_pca:, 0.min(), digits_pca:, 0.max()) plt.ylim(digits_pca:, 1.min(), digits_pca:, 1.max()) for i in range(len(digits.data)):
# 散布図を数字でプロット
plt.text(digits_pcai, 0, digits_pcai, 1, str(digits.targeti), color = colors[digits.targeti], fontdict={'weight': 'bold', 'size': 9})
plt.xlabel("First principal component")
plt.ylabel("Second principal component")
https://gyazo.com/2222a4328b4a9b70ae8a01e2ae8f52eb
digitsデータセットにt-SNEを適用する
code: Python
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.manifold import TSNE
digits = load_digits()
tsne = TSNE(random_state=42)
# fitではなくfit_transformを用いる
# tTSNEにはtransformメソッドがない
digits_tsne = tsne.fit_transform(digits.data)
plt.figure(figsize=(10, 10))
plt.xlim(digits_tsne:, 0.min(), digits_tsne:, 0.max() + 1) plt.ylim(digits_tsne:, 1.min(), digits_tsne:, 1.max() + 1) for i in range(len(digits.data)):
# 点ではなく数字をテキストとしてプロットする
plt.text(digits_tsnei, 0, digits_tsnei, 1, str(digits.targeti), color = colors[digits.targeti], fontdict={'weight': 'bold', 'size': 9})
plt.xlabel("t-SNE feature 0")
plt.ylabel("t-SNE feature 1")
https://gyazo.com/430edb48f34b4a801cd48c0a52028948
t-SNEの結果は驚くべきものです。すべてのクラスがかなり明確に分離されています。この方法では、クラスラベルの知識をまったく使っていません。これは完全に教師なし学習です。にも関わらず、データをクラスごとにきれいに分離して2次元に表現する方法を、もとの空間の点の近さだけを使って発見したわけです。